package com.hualala.supplychain.methodext;

import com.alibaba.fastjson.JSONObject;
import com.hualala.supplychain.methodext.annotation.DoMethodExtAfter;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.joor.Reflect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * Reflect
 *
 *     Reflect.on 包裹一个类或者对象，表示在这个类或对象上进行反射，类的值可以使Class,也可以是完整的类名（包含包名信息）
 *     Reflect.create 用来调用之前的类的构造方法，有两种重载，一种有参数，一种无参数
 *     Reflect.call 方法调用，传入方法名和参数，如有返回值还需要调用get
 *     Reflect.get 获取（field和method返回）值相关，会进行类型转换，常与call和field组合使用
 *     Reflect.field 获取属性值相关，需要调用get获取该值
 *     Reflect.set 设置属性相关。
 */
@Aspect
@Component
@Log4j2
public class DoMethodExtAfterPoint {

    @Autowired
    private ApplicationContext applicationContext;

    @Pointcut("@annotation(com.hualala.supplychain.methodext.annotation.DoMethodExtAfter)")
    public void aopPoint() {
    }

    @AfterReturning(value = "aopPoint() && @annotation(doMethodExtAfter)", returning = "returnValue")
    public void omsLogAfterReturn(JoinPoint jp, DoMethodExtAfter doMethodExtAfter, JSONObject returnValue) throws Throwable{
        if(returnValue!=null){
            String tempClassName = doMethodExtAfter.className();
            // 获取拦截方法
            String methodName = doMethodExtAfter.method();
            Reflect.on(applicationContext.getBean(tempClassName)).call(methodName, returnValue);
        }
    }
}
